import { TriggerOpTypes, hasChanged } from "../../utils";
import trigger from "../../effect/trigger";

const setHandler: ProxyHandler<object>["set"] = (target, key, newValue) => {
  // 在设置之前需要缓存一下旧值和旧length
  const oldValue = Reflect.get(target, key);
  const oldLength = Array.isArray(target) ? target.length : void 0;
  const result = Reflect.set(target, key, newValue);
  if (hasChanged(oldValue, newValue)) {
    // 派发更新
    trigger(target, TriggerOpTypes.SET, key);

    // 手动判断length，当length隐式改变时，手动对length进行派发更新
    if (Array.isArray(target) && oldLength !== target.length) {
      // 显式更改length时，会自动触发set的派发更新，不需要再手动对length进行派发更新
      if (key !== "length") trigger(target, TriggerOpTypes.SET, "length");
      else {
        // 显式更改length时，还需要处理length<oldLength的情况，手动对delete进行派发更新
        for (let i = target.length; i < oldLength!; i++) {
          trigger(target, TriggerOpTypes.DELETE, i.toString());
        }
      }
    }
  }

  return result;
};

export default setHandler;
